package hasthi.tools.analyze;

import hasthi.common.HasthiException;
import hasthi.common.HasthiException.FaultCode;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.Vector;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.math.stat.descriptive.DescriptiveStatistics;

public class SystemEventsParser {
    public static Pattern failureInSystemPattern = Pattern.compile("\\(([0-9]*)\\)Failure In the managed system detected");
    public static Pattern systemRecoveredPattern = Pattern.compile("\\(([0-9]*)\\)Managed system recovered");
    public static Pattern resourceStartedPattern = Pattern.compile("\\(([0-9]*)\\)Resource (.*?) Started");
    public static Pattern resourceStoppedPattern = Pattern.compile("\\(([0-9]*)\\)Resource (.*?) Stopped");
    public static Pattern resourceJoinRequestPattern = Pattern.compile("\\(([0-9]*)\\)Join Request.*?\\((.*?)\\)");
    public static Pattern resourceJoinedPattern = Pattern.compile("\\(([0-9]*)\\)Join Completed.*?\\((.*?) to");
    public static Pattern actionCompletedPattern = Pattern.compile("\\(([0-9]*)\\).*?Action .*?:(.*?)\\|(.*?) Completed in \\(([0-9]*)\\) ms");
    public static Pattern actionFailedPattern = Pattern.compile("\\(([0-9]*)\\).*?Action .*?:(.*?)\\|(.*?) Failed");
    public static Pattern decideResourceCrashedPattern = Pattern.compile("\\(([0-9]*)\\).*?Decide resource (.*?) has crashed");
    public static Pattern systemFailedPattern = Pattern.compile("\\(([0-9]*)\\).*?System Error Occured\\(Real time\\)");
    
    
    //(1231157880684)Join Request(tyr05.cs.indiana.edu)#http://129.79.240.90:48503
    //Action Manager:hasthi.actuators.CreateServiceAction|{http://www.extreme.indiana.edu/lead}FactoryService Completed in (6499) ms
    //(1231101461299)Action Manager:hasthi.actuators.CreateServiceAction|{http://extreme.indiana.edu/xregistry2/2007_02_21}IXregistry Failed#
    
    private Map<String,Boolean> tomcatBasedServices = new HashMap<String, Boolean>(); 
    
    private Map<String,DescriptiveStatistics> tomcatBasedActionData = new HashMap<String, DescriptiveStatistics>();
    private Map<String,DescriptiveStatistics> otherActionData = new HashMap<String, DescriptiveStatistics>();
    
    private DescriptiveStatistics systemRecoveryTimeAfterDetected = DescriptiveStatistics.newInstance();
    private DescriptiveStatistics systemRecoveryTimeReal = DescriptiveStatistics.newInstance();
    
    
    private Map<String,ResourceLifeCycle> resourceDataMap = new HashMap<String, ResourceLifeCycle>();
    private SystemLifeCycle systemLifeCycle = new SystemLifeCycle();
    
    private Set<Long> recoveryTimes = new TreeSet<Long>();
    
    private List<String>  failedResources = new Vector<String>(); 
    
    private boolean sorted = false;
    
    public void addEvent(String str)throws HasthiException{
        try {
            Matcher matcher;
            
            if((matcher = hasMatch(str, failureInSystemPattern)) != null){
                long time = Long.valueOf(matcher.group(1));
                if(systemLifeCycle.systemRecovered > time){
                    systemRecoveryTimeAfterDetected.addValue(systemLifeCycle.systemRecovered -time);
                    systemLifeCycle.systemRecovered = -1;
                    systemLifeCycle.systemFailureDetected = -1;
                }else{
                    systemLifeCycle.systemFailureDetected = time;
                }
            }else if((matcher = hasMatch(str, systemRecoveredPattern)) != null){
                long time = Long.valueOf(matcher.group(1));
                recoveryTimes.add(time);
                if(systemLifeCycle.systemFailed >0){
                    systemRecoveryTimeReal.addValue(time - systemLifeCycle.systemFailed);
                    systemLifeCycle.systemRecovered = -1;
                    systemLifeCycle.systemFailed = -1;
                }else if(systemLifeCycle.systemFailureDetected >0){
                    systemRecoveryTimeAfterDetected.addValue(time - systemLifeCycle.systemFailureDetected);
                    systemLifeCycle.systemRecovered = -1;
                    systemLifeCycle.systemFailureDetected = -1;
                }else{
                    systemLifeCycle.systemRecovered = time;
                }
            }else if((matcher = hasMatch(str, systemFailedPattern)) != null){
                long time = Long.valueOf(matcher.group(1));
                if(systemLifeCycle.systemRecovered > time){
                    systemRecoveryTimeReal.addValue(systemLifeCycle.systemRecovered -time);
                    systemLifeCycle.systemRecovered = -1;
                    systemLifeCycle.systemFailureDetected= -1;
                }else{
                    systemLifeCycle.systemFailed = time;
                }
            }else if((matcher = hasMatch(str, resourceStartedPattern)) != null){
                long time = Long.valueOf(matcher.group(1));
                String resourceName = matcher.group(2);
                ResourceLifeCycle resourceLifeCycle = resourceDataMap.get(resourceName);
                if(resourceLifeCycle == null){
                    resourceLifeCycle = new ResourceLifeCycle();
                    resourceDataMap.put(resourceName, resourceLifeCycle);
                }
                resourceLifeCycle.resourceStarted = time;
            }else if((matcher = hasMatch(str, resourceStoppedPattern)) != null){
                long time = Long.valueOf(matcher.group(1));
                String resourceName = matcher.group(2);
                ResourceLifeCycle resourceLifeCycle = resourceDataMap.get(resourceName);
                if(resourceLifeCycle == null){
                    resourceLifeCycle = new ResourceLifeCycle();
                    resourceDataMap.put(resourceName, resourceLifeCycle);
                }
                resourceLifeCycle.resourceFailed = time;
                System.out.println("Resource Stopped "+ resourceName);
            }else if((matcher = hasMatch(str, resourceJoinRequestPattern)) != null){
                long time = Long.valueOf(matcher.group(1));
                String resourceName = matcher.group(2);
                ResourceLifeCycle resourceLifeCycle = resourceDataMap.get(resourceName);
                if(resourceLifeCycle == null){
                    resourceLifeCycle = new ResourceLifeCycle();
                    resourceDataMap.put(resourceName, resourceLifeCycle);
                }
                if(resourceLifeCycle.resourceJoinRequested < time){
                    resourceLifeCycle.resourceJoinRequested = time;    
                }
            }else if((matcher = hasMatch(str, resourceJoinedPattern)) != null){
                long time = Long.valueOf(matcher.group(1));
                String resourceName = matcher.group(2);
                ResourceLifeCycle resourceLifeCycle = resourceDataMap.get(resourceName);
                if(resourceLifeCycle == null){
                    resourceLifeCycle = new ResourceLifeCycle();
                    resourceDataMap.put(resourceName, resourceLifeCycle);
                }
                resourceLifeCycle.resourceJoined = time;
            }else if((matcher = hasMatch(str, decideResourceCrashedPattern)) != null){
                long time = Long.valueOf(matcher.group(1));
                String resourceName = matcher.group(2);
                ResourceLifeCycle resourceLifeCycle = resourceDataMap.get(resourceName);
                if(resourceLifeCycle == null){
                    resourceLifeCycle = new ResourceLifeCycle();
                    resourceDataMap.put(resourceName, resourceLifeCycle);
                }
                resourceLifeCycle.failureDetected = time;    
                System.out.println("Failure detected "+ resourceName + " "+ time );
                failedResources.add(resourceName);
                if(failedResources.size() > 100){
                    failedResources.remove(0);
                }
            }else if((matcher = hasMatch(str, actionCompletedPattern)) != null){
                long time = Long.valueOf(matcher.group(1));
                String actionName = matcher.group(2);
                String resourceName = matcher.group(3);
                long time4Action = Long.valueOf(matcher.group(4));
                
                for(int i = failedResources.size()-1;i>0;i--){
                    String name = failedResources.get(i);
                    if(name.startsWith(resourceName)){
                        resourceName = name;
                    }
                }
                
                
                ResourceLifeCycle resourceLifeCycle = resourceDataMap.get(resourceName);
                if(resourceLifeCycle == null){
                    resourceLifeCycle = new ResourceLifeCycle();
                    resourceDataMap.put(resourceName, resourceLifeCycle);
                }
                resourceLifeCycle.actionTime = time-time4Action;
                resourceLifeCycle.actionTakenTime = time4Action;
                //System.out.println("DATA             "+resourceName + " "+ time4Action + " "+ time);
                
                if(tomcatBasedServices.containsKey(actionName)){
                    DescriptiveStatistics descriptiveStatistics = tomcatBasedActionData.get(actionName);
                    if(descriptiveStatistics == null){
                        descriptiveStatistics = DescriptiveStatistics.newInstance();
                        tomcatBasedActionData.put(actionName, descriptiveStatistics);
                    }
                    descriptiveStatistics.addValue(time4Action);
                }else{
                    DescriptiveStatistics descriptiveStatistics = otherActionData.get(actionName);
                    if(descriptiveStatistics == null){
                        descriptiveStatistics = DescriptiveStatistics.newInstance();
                        otherActionData.put(actionName, descriptiveStatistics);
                    }
                    descriptiveStatistics.addValue(time4Action);
                }
            }else{
                if((str.contains("Coordinator") && str.contains("Mgrs")) 
                        || str.contains("Envelope xmlns") ||str.contains("null") 
                        ||str.contains("Instance already exists:") ||str.contains("Remove Assigment ") 
                        || str.contains("Assigment ") || str.contains("Coordiantor Control loop is turned Off")
                        ||str.contains("Resource JoinFailed:Unable to connect to the service ") || str.contains("HostAgent")
                        ||str.contains("Trigger recover workflows") || str.contains("LEAD Service ")
                        //||(str.contains("Action") && str.contains("Failed"))
                        ||hasMatch(str, actionFailedPattern) != null
                        ){
                    
                }else{
                    System.out.println("Unknown Event "+ str);
                }
            }
        } catch (Throwable e) {
            throw new HasthiException("Error Processing "+str + ":"+e.getMessage(),e,FaultCode.LocalError);
        }
    }
    public void parseFromAFile(String fileName,PerfData data)throws HasthiException{
        try {
            BufferedReader br = new BufferedReader(new FileReader(fileName));
            String line;
            if(sorted){
                TreeSet<String> orderedList = new TreeSet<String>();
                while((line = br.readLine())!= null ){
                    int index = line.indexOf("(12"); 
                    if(index > 0){
                        orderedList.add(line.substring(index));
                        
                    }
                }
                for(String sortedLine:orderedList){
                    //System.out.println(sortedLine);
                    addEvent(sortedLine);  
                }
            }else{
                while((line = br.readLine())!= null ){
                    addEvent(line);
                }
            }
            processDataAndAdd(data);
        } catch (FileNotFoundException e) {
            throw new HasthiException(e,FaultCode.LocalError);
        } catch (IOException e) {
            throw new HasthiException(e,FaultCode.LocalError);
        }
    }
    
    public String parseFromAFile(String fileName)throws HasthiException{
        try {
            BufferedReader br = new BufferedReader(new FileReader(fileName));
            String line;
            if(sorted){
                TreeSet<String> orderedList = new TreeSet<String>();
                while((line = br.readLine())!= null ){
                    int index = line.indexOf("(12"); 
                    if(index > 0){
                        orderedList.add(line.substring(index));
                        
                    }
                }
                for(String sortedLine:orderedList){
                    //System.out.println(sortedLine);
                    addEvent(sortedLine);  
                }
            }else{
                while((line = br.readLine())!= null ){
                    addEvent(line);
                }
            }
            return getSummery();
        } catch (FileNotFoundException e) {
            throw new HasthiException(e,FaultCode.LocalError);
        } catch (IOException e) {
            throw new HasthiException(e,FaultCode.LocalError);
        }
    }
    
    public void printSummery(){
        System.out.println(getSummery());
    }
    
    public String getSummery(){
        return processData().toString();
    }
    
    public String getSummeryAsHtml(){
        return processData().toHtml();
    }

    public static class PerfData{
        DescriptiveStatistics time2Join = DescriptiveStatistics.newInstance();
        DescriptiveStatistics time2Detect = DescriptiveStatistics.newInstance();
        DescriptiveStatistics time2TRiggerAction = DescriptiveStatistics.newInstance();
        DescriptiveStatistics time2Recover = DescriptiveStatistics.newInstance();
        DescriptiveStatistics systemRecoveryTimeAfterDetected = DescriptiveStatistics.newInstance();
        DescriptiveStatistics systemRecoveryTimeReal = DescriptiveStatistics.newInstance();
        DescriptiveStatistics systemRecoveryTimeReal2 = DescriptiveStatistics.newInstance();
        private Map<String,DescriptiveStatistics> tomcatBasedActionData = new HashMap<String, DescriptiveStatistics>();
        private Map<String,DescriptiveStatistics> otherActionData = new HashMap<String, DescriptiveStatistics>();

        public FormattedTable getDetails(){
            FormattedTable table = new FormattedTable("Key\tmean\tmedian\tcov\tsize\tmin\tmax\tconfInterval");
            table.addLine("SystemRecoveryTime(ms) " + AnalyzeUtils.formatOneWithConfInterval(systemRecoveryTimeReal));   
            table.addLine("SystemRecoveryTime2(ms) " + AnalyzeUtils.formatOneWithConfInterval(systemRecoveryTimeReal2));
            table.addLine("SystemRecoveryTimeAfterDetected(ms) " + AnalyzeUtils.formatOneWithConfInterval(systemRecoveryTimeAfterDetected));

            for(String key:otherActionData.keySet()){
                DescriptiveStatistics data = otherActionData.get(key);
                table.addLine(key + "(ms) " + AnalyzeUtils.formatOne(data));
            }
            table.addLine("time2Join(ms)          " + AnalyzeUtils.formatOneWithConfInterval(time2Join));
            
            System.out.println(Arrays.toString(AnalyzeUtils.findFreqDistribution(time2Detect)));
            table.addLine("time4Failure2Detect(ms)        " + AnalyzeUtils.formatOneWithConfInterval(AnalyzeUtils.removeOutliners(AnalyzeUtils.removeOutliners(time2Detect))));
            //table.addLine("time2Detect(ms)        " + AnalyzeUtils.formatOne(time2Detect));
            table.addLine("time2FromDetect2RiggerAction(ms) " + AnalyzeUtils.formatOneWithConfInterval(time2TRiggerAction));
            table.addLine("time2RecoveryAction(ms)       " + AnalyzeUtils.formatOneWithConfInterval(time2Recover));

//            table.addLine("time2Join(ms)          " + AnalyzeUtils.formatOne(AnalyzeUtils.removeOutliners(time2Join)));
//            table.addLine("time2Detect(ms)        " + AnalyzeUtils.formatOne(AnalyzeUtils.removeOutliners(time2Detect)));
//            table.addLine("time2TRiggerAction(ms) " + AnalyzeUtils.formatOne(AnalyzeUtils.removeOutliners(time2TRiggerAction)));
//            table.addLine("time2Recover(ms)       " + AnalyzeUtils.formatOne(AnalyzeUtils.removeOutliners(time2Recover)));
            int[] freq = AnalyzeUtils.findFreqDistribution(time2Detect);
            System.out.println(Arrays.toString(freq));
            
            return table;

        }
    }
    
    private void merge(DescriptiveStatistics src,DescriptiveStatistics dest){
        for(double val:src.getValues()){
            dest.addValue(val);    
        }
    }
    
    public void processDataAndAdd(PerfData perfData){
        merge(systemRecoveryTimeReal, perfData.systemRecoveryTimeReal);
        merge(systemRecoveryTimeAfterDetected, perfData.systemRecoveryTimeAfterDetected);
        
        Set<String> keys = new TreeSet<String>();
        keys.addAll(otherActionData.keySet());
        keys.addAll(perfData.otherActionData.keySet());
        
        for(String key:keys){
            DescriptiveStatistics dest = perfData.otherActionData.get(key);
            DescriptiveStatistics src = otherActionData.get(key);
            if(dest != null){
                if(src != null){
                    merge(src, dest);
                }
            }else{
                if(src != null){
                    perfData.otherActionData.put(key, src);
                }
            }
        }
        
        DescriptiveStatistics time2Join = perfData.time2Join;
        DescriptiveStatistics time2Detect = perfData.time2Detect;
        DescriptiveStatistics time2TRiggerAction = perfData.time2TRiggerAction;
        DescriptiveStatistics time2Recover = perfData.time2Recover;
        DescriptiveStatistics systemRecoveryTimeReal2 = perfData.systemRecoveryTimeReal2;
        
        for(String key:resourceDataMap.keySet()){
            ResourceLifeCycle rdata = resourceDataMap.get(key);
            long startTime = rdata.resourceStarted>0?rdata.resourceStarted:rdata.resourceJoinRequested;
            if(startTime > 0 && rdata.resourceJoined > 0 && rdata.resourceJoined > startTime){
                if(rdata.resourceJoined - startTime > 30000){
                    System.out.println("too long between join and start ="+((rdata.resourceJoined - startTime)/(100*60))+  " minutes " +new Date(rdata.resourceJoined)+ " - " + new Date(startTime));
                }else{
                    time2Join.addValue(rdata.resourceJoined - startTime);    
                }
            }
            if(rdata.actionTakenTime > 0){
                System.out.println("action time = " +rdata.actionTakenTime);                
            }

            
            if(rdata.resourceFailed > 0 && rdata.failureDetected > 0){
                if(rdata.failureDetected > rdata.resourceFailed){
                    time2Detect.addValue(rdata.failureDetected - rdata.resourceFailed);
                }else{
                    System.out.println(" detected before failure "+ (rdata.failureDetected - rdata.resourceFailed)/(1000) +"seconds");
                }
            }
//            if(rdata.resourceFailed > 0 && rdata.actionTime > rdata.resourceFailed){
//                time2TRiggerAction.addValue(rdata.actionTime - rdata.resourceFailed);
//            }
//            if(rdata.resourceFailed > 0 && rdata.actionTakenTime > 0 && rdata.actionTime > 0 && rdata.actionTime > rdata.resourceFailed){
//                time2Recover.addValue(rdata.actionTakenTime - rdata.resourceFailed + rdata.actionTime);
//            }
            if(rdata.failureDetected > 0 && rdata.actionTime > rdata.failureDetected){
                time2TRiggerAction.addValue(rdata.actionTime - rdata.failureDetected);
            }
            if(rdata.actionTakenTime > 0){
                time2Recover.addValue(rdata.actionTakenTime);
            }
            if(rdata.resourceFailed > 0 && rdata.actionTime > rdata.resourceFailed){
                for(long recoveryTime:recoveryTimes){
                    if(rdata.actionTime < recoveryTime){
                        systemRecoveryTimeReal2.addValue(recoveryTime - rdata.resourceFailed);   
                        break;
                    }
                }
            }
            //buf.append(key + "=" +rdata);
        }
    }

    
    
    public FormattedTable processData(){
        PerfData data = new PerfData();
        processDataAndAdd(data);
        return data.getDetails();
//        FormattedTable table = new FormattedTable("Key\tmean\tmedian\tcov\tsize\tmin\tmax\tconfInterval");
//        table.addLine("SystemRecoveryTime(ms) " + AnalyzeUtils.formatOne(systemRecoveryTimeReal));        
//        table.addLine("SystemRecoveryTimeAfterDetected(ms) " + AnalyzeUtils.formatOne(systemRecoveryTimeAfterDetected));
//        
//        for(String key:tomcatBasedActionData.keySet()){
//            DescriptiveStatistics data = tomcatBasedActionData.get(key);
//            table.addLine(key + "_tomcat(ms) " + AnalyzeUtils.formatOne(data));
//        }
//        
//        for(String key:otherActionData.keySet()){
//            DescriptiveStatistics data = otherActionData.get(key);
//            table.addLine(key + "(ms) " + AnalyzeUtils.formatOne(data));
//        }
//        DescriptiveStatistics time2Join = DescriptiveStatistics.newInstance();
//        DescriptiveStatistics time2Detect = DescriptiveStatistics.newInstance();
//        DescriptiveStatistics time2TRiggerAction = DescriptiveStatistics.newInstance();
//        DescriptiveStatistics time2Recover = DescriptiveStatistics.newInstance();
//        
//        for(String key:resourceDataMap.keySet()){
//            ResourceLifeCycle rdata = resourceDataMap.get(key);
//            long startTime = rdata.resourceStarted>0?rdata.resourceStarted:rdata.resourceJoinRequested;
//            if(startTime > 0 && rdata.resourceJoined > 0 && rdata.resourceJoined > startTime){
//                if(rdata.resourceJoined - startTime > 30000){
//                    System.out.println("too long between join and start ="+((rdata.resourceJoined - startTime)/(100*60))+  " minutes " +new Date(rdata.resourceJoined)+ " - " + new Date(startTime));
//                }else{
//                    time2Join.addValue(rdata.resourceJoined - startTime);    
//                }
//            }
//            if(rdata.actionTakenTime > 0){
//                System.out.println("action time = " +rdata.actionTakenTime);                
//            }
//
//            
//            if(rdata.resourceFailed > 0 && rdata.failureDetected > 0){
//                if(rdata.failureDetected > rdata.resourceFailed){
//                    time2Detect.addValue(rdata.failureDetected - rdata.resourceFailed);
//                }else{
//                    System.out.println(" detected before failure "+ (rdata.failureDetected - rdata.resourceFailed)/(1000) +"seconds");
//                }
//            }
////            if(rdata.resourceFailed > 0 && rdata.actionTime > rdata.resourceFailed){
////                time2TRiggerAction.addValue(rdata.actionTime - rdata.resourceFailed);
////            }
////            if(rdata.resourceFailed > 0 && rdata.actionTakenTime > 0 && rdata.actionTime > 0 && rdata.actionTime > rdata.resourceFailed){
////                time2Recover.addValue(rdata.actionTakenTime - rdata.resourceFailed + rdata.actionTime);
////            }
//            
//              if(rdata.failureDetected > 0 && rdata.actionTime > rdata.failureDetected){
//                  time2TRiggerAction.addValue(rdata.actionTime - rdata.failureDetected);
//              }
//              if(rdata.actionTakenTime > 0){
//                  time2Recover.addValue(rdata.actionTakenTime);
//              }
//            //buf.append(key + "=" +rdata);
//        }
//                            
//        table.addLine("time2Join(ms)          " + AnalyzeUtils.formatOne(time2Join));
//        table.addLine("time4Failure2Detect(ms)        " + AnalyzeUtils.formatOne(time2Detect));
//        table.addLine("time2FromDetect2RiggerAction(ms) " + AnalyzeUtils.formatOne(time2TRiggerAction));
//        table.addLine("time2RecoveryAction(ms)       " + AnalyzeUtils.formatOne(time2Recover));
//        return table;
        
//        StringBuffer buf = new StringBuffer();
//        buf.append("System Recovery Time \tmean\tmedian\tcov\tsize\tmin\tmax");
//        buf.append("System Recovery Time " + AnalyzeUtils.formatOne(systemRecoveryTime));
//        
//        for(String key:tomcatBasedActionData.keySet()){
//            DescriptiveStatistics data = tomcatBasedActionData.get(key);
//            buf.append(key + "(tomcat)" + AnalyzeUtils.formatOne(data));
//        }
//        
//        for(String key:otherActionData.keySet()){
//            DescriptiveStatistics data = otherActionData.get(key);
//            buf.append(key + " " + AnalyzeUtils.formatOne(data));
//        }
//        
//        DescriptiveStatistics time2Join = DescriptiveStatistics.newInstance();
//        DescriptiveStatistics time2Detect = DescriptiveStatistics.newInstance();
//        DescriptiveStatistics time2TRiggerAction = DescriptiveStatistics.newInstance();
//        DescriptiveStatistics time2Recover = DescriptiveStatistics.newInstance();
//        for(String key:resourceDataMap.keySet()){
//            ResourceLifeCycle rdata = resourceDataMap.get(key);
//            long startTime = rdata.resourceStarted>0?rdata.resourceStarted:rdata.resourceJoinRequested;
//            if(startTime > 0 && rdata.resourceJoined > 0 && rdata.resourceJoined > startTime){
//                if(rdata.resourceJoined - startTime > 30000){
//                    buf.append(new Date(rdata.resourceJoined)+ " - " + new Date(startTime));
//                }else{
//                    time2Join.addValue(rdata.resourceJoined - startTime);    
//                }
//            }
//            if(rdata.resourceFailed > 0 && rdata.failureDetected > 0 && rdata.failureDetected > rdata.resourceFailed){
//                time2Detect.addValue(rdata.failureDetected - rdata.resourceFailed);
//            }
//            if(rdata.resourceFailed > 0 && rdata.actionTakenTime > 0 && rdata.actionTakenTime > rdata.resourceFailed){
//                time2TRiggerAction.addValue(rdata.actionTakenTime - rdata.resourceFailed);
//            }
//            if(rdata.resourceFailed > 0 && rdata.actionTakenTime > 0 && rdata.actionTime > 0 && rdata.actionTakenTime > rdata.resourceFailed){
//                time2Recover.addValue(rdata.actionTakenTime - rdata.resourceFailed + rdata.actionTime);
//            }
//            //buf.append(key + "=" +rdata);
//        }
//                            
//        buf.append("time2Join            " + AnalyzeUtils.formatOne(time2Join));
//        buf.append("time2Detect          " + AnalyzeUtils.formatOne(time2Detect));
//        buf.append("time2TRiggerAction   " + AnalyzeUtils.formatOne(time2TRiggerAction));
//        buf.append("time2Recover         " + AnalyzeUtils.formatOne(time2Recover));
//        return buf.toString();

    }
    
    public static final Matcher hasMatch(String str,Pattern p){
        Matcher matcher = p.matcher(str);
        if(matcher.find()){
            return matcher;   
        }else{
            return null;
        }
    }
    
    
    public class ResourceLifeCycle{
        long resourceStarted = -1;
        long resourceJoinRequested = -1;
        long resourceJoined = -1;
        long resourceFailed = -1;
        long failureDetected = -1;
        long actionTakenTime = -1;
        long actionTime = -1;
        @Override
        public String toString() {
            return new StringBuffer().append("resourceStarted=").append(resourceStarted).append(" ")
                .append("resourceJoinRequested=").append(resourceJoinRequested)
                .append("resourceJoined=").append(resourceJoined).toString();
        }
        
    }
    
    
    public class SystemLifeCycle{
        long systemFailed = -1;
        long systemFailureDetected = -1;
        long systemRecovered = -1;
    }
    public static void main(String[] args) throws HasthiException {
        File input = new File("/u/hperera/docs/perfdata/hasthi/lead-data/service-failure-test.log");
//        File input = new File("/u/hperera/docs/perfdata/hasthi/lead-data/set4");
        PerfData data = new PerfData();
        if(input.isDirectory()){
//          List<String> list=  new ArrayList<String>();
          for(File file:input.listFiles()){
              SystemEventsParser parser = new SystemEventsParser();
              parser.parseFromAFile(file.getAbsolutePath(),data);
          }
        }else{
            SystemEventsParser parser = new SystemEventsParser();
            parser.parseFromAFile(input.getAbsolutePath(),data);
        }
        System.out.println(data.getDetails());
    }
}
